<template>
  <view class="container">
    <view class="header">
      <text class="title">音频播放器</text>
    </view>
    
	<audio src="http://127.0.0.1:8080/getSounds?text=你好" controls="true"></audio>
    <view class="controls">
      <button @click="fetchAudio" :disabled="isLoading" class="btn">
        {{ isLoading ? '加载中...' : '获取音频' }}
      </button>
      
      <button @click="togglePlay" :disabled="!audioData" class="btn">
        {{ isPlaying ? '暂停' : '播放' }}
      </button>
      
      <button @click="stopAudio" :disabled="!isPlaying" class="btn">
        停止
      </button>
    </view>
    
    <view class="status">
      <text v-if="statusMessage" class="status-text">{{ statusMessage }}</text>
      <text v-if="errorMessage" class="error-text">{{ errorMessage }}</text>
    </view>
    
    <view class="progress-container" v-if="duration > 0">
      <slider 
        :value="currentTime" 
        :max="duration" 
        @changing="onSliderChanging" 
        @change="onSliderChange"
        activeColor="#4a90e2"
        block-size="12"
      />
      <view class="time-display">
        <text>{{ formatTime(currentTime) }}</text>
        <text>{{ formatTime(duration) }}</text>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      audioData: null,
      audioContext: null,
      audioSource: null,
      isPlaying: false,
      isLoading: false,
      statusMessage: '',
      errorMessage: '',
      currentTime: 0,
      duration: 0,
      updateInterval: null,
      isSeeking: false
    };
  },
  methods: {
    async fetchAudio() {
      this.isLoading = true;
      this.statusMessage = '正在获取音频...';
      this.errorMessage = '';
      
      try {
        const response = await uni.request({
          url: 'http://127.0.0.1:8080/getSounds',
          method: 'GET',
          responseType: 'arraybuffer'
        });
        
		console.log(response)
        if (response.statusCode === 200) {
          const data = response.data;
          
          // 检查返回的数据是否是有效的音频数据
          if (data && data.byteLength > 0) {
            this.audioData = data;
            this.statusMessage = '音频加载成功，点击播放按钮开始播放';
            this.prepareAudio();
          } else {
            throw new Error('无效的音频数据');
          }
        } else {
          throw new Error(`请求失败，状态码: ${response.statusCode}`);
        }
      } catch (error) {
        console.error('获取音频失败:', error);
        this.errorMessage = `获取音频失败: ${error.message}`;
      } finally {
        this.isLoading = false;
      }
    },
    
    prepareAudio() {
      // 如果已经有音频在播放，先停止
      if (this.audioContext) {
        this.stopAudio();
      }
      
      // 创建音频上下文
      this.audioContext = uni.createInnerAudioContext();
      
      // 设置音频源为获取到的二进制数据
      // 注意：Uniapp的InnerAudioContext不支持直接设置ArrayBuffer
      // 我们需要将二进制数据转换为临时URL
      const blob = new Blob([this.audioData], { type: 'audio/mpeg' });
      const audioUrl = URL.createObjectURL(blob);
      this.audioContext.src = audioUrl;
      
      // 设置事件监听
      this.audioContext.onPlay(() => {
        this.isPlaying = true;
        this.statusMessage = '正在播放音频';
        this.startProgressUpdate();
      });
      
      this.audioContext.onPause(() => {
        this.isPlaying = false;
        this.statusMessage = '音频已暂停';
        this.stopProgressUpdate();
      });
      
      this.audioContext.onStop(() => {
        this.isPlaying = false;
        this.statusMessage = '音频已停止';
        this.stopProgressUpdate();
        this.currentTime = 0;
      });
      
      this.audioContext.onEnded(() => {
        this.isPlaying = false;
        this.statusMessage = '音频播放结束';
        this.stopProgressUpdate();
        this.currentTime = this.duration;
      });
      
      this.audioContext.onError((err) => {
        console.error('音频播放错误:', err);
        this.errorMessage = `播放错误: ${err}`;
        this.isPlaying = false;
        this.stopProgressUpdate();
      });
      
      this.audioContext.onCanplay(() => {
        // 获取音频时长
        this.duration = this.audioContext.duration;
      });
    },
    
    togglePlay() {
      if (!this.audioData) return;
      
      if (this.isPlaying) {
        this.audioContext.pause();
      } else {
        this.audioContext.play();
      }
    },
    
    stopAudio() {
      if (this.audioContext) {
        this.audioContext.stop();
      }
    },
    
    startProgressUpdate() {
      this.stopProgressUpdate();
      this.updateInterval = setInterval(() => {
        if (!this.isSeeking && this.audioContext) {
          this.currentTime = this.audioContext.currentTime;
        }
      }, 200);
    },
    
    stopProgressUpdate() {
      if (this.updateInterval) {
        clearInterval(this.updateInterval);
        this.updateInterval = null;
      }
    },
    
    onSliderChanging(e) {
      this.isSeeking = true;
      this.currentTime = e.detail.value;
    },
    
    onSliderChange(e) {
      this.currentTime = e.detail.value;
      if (this.audioContext) {
        this.audioContext.seek(this.currentTime);
      }
      this.isSeeking = false;
    },
    
    formatTime(seconds) {
      const mins = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
    }
  },
  
  beforeDestroy() {
    // 组件销毁时清理资源
    if (this.audioContext) {
      this.audioContext.destroy();
      this.audioContext = null;
    }
    this.stopProgressUpdate();
  }
};
</script>

<style>
.container {
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.header {
  margin-bottom: 30px;
}

.title {
  font-size: 24px;
  font-weight: bold;
  color: #333;
}

.controls {
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin-bottom: 20px;
  gap: 15px;
}

.btn {
  padding: 10px 20px;
  background-color: #4a90e2;
  color: white;
  border-radius: 5px;
  font-size: 16px;
}

.btn:disabled {
  background-color: #cccccc;
  color: #666666;
}

.status {
  margin-bottom: 20px;
  min-height: 40px;
}

.status-text {
  color: #4a90e2;
  font-size: 16px;
}

.error-text {
  color: #e74c3c;
  font-size: 16px;
}

.progress-container {
  width: 80%;
  margin-top: 20px;
}

.time-display {
  width: 100%;
  display: flex;
  justify-content: space-between;
  margin-top: 5px;
  font-size: 14px;
  color: #666;
}
</style>